package com.example.security.service;

import com.example.security.entity.SysPermission;
import com.example.security.vo.MenuVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class RbacService {

    private final PermissionService permissionService;
    private final RoleService roleService;
    
    // 检查用户是否有权限
    public boolean hasPermission(Long userId, String permission) {
        Set<String> permissions = permissionService.getUserPermissions(userId);
        return permissions.contains(permission);
    }
    
    // 检查用户是否有角色
    public boolean hasRole(Long userId, String roleCode) {
        List<String> roleCodes = roleService.getUserRoleCodes(userId);
        return roleCodes.contains(roleCode);
    }
    
    // 获取用户菜单
    public List<MenuVO> getUserMenus(Long userId) {
        Set<String> permissions = permissionService.getUserPermissions(userId);
        List<SysPermission> allMenus = permissionService.getMenuTree();
        return filterMenus(allMenus, permissions);
    }
    
    // 过滤用户有权限的菜单
    private List<MenuVO> filterMenus(List<SysPermission> menus, Set<String> permissions) {
        return menus.stream()
            .filter(menu -> hasPermission(permissions, menu))
            .map(menu -> {
                MenuVO vo = new MenuVO();
                BeanUtils.copyProperties(menu, vo);
                if (!CollectionUtils.isEmpty(menu.getChildren())) {
                    vo.setChildren(filterMenus(menu.getChildren(), permissions));
                }
                return vo;
            })
            .collect(Collectors.toList());
    }

    // 检查权限
    private boolean hasPermission(Set<String> permissions, SysPermission menu) {
        // 如果是菜单，直接返回true
        if (menu.getType() == 1) {
            return true;
        }
        // 如果是按钮，检查权限标识
        return permissions.contains(menu.getEnname());
    }
} 